package cn.initcap.designpattern.pattern.creational.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * @author initcap
 * @date 2018/8/28 AM9:09
 */
public class LazySingleton {
    private static LazySingleton lazySingleton = null;
    /**
     * 无论使用多么复杂的逻辑，都不能真正的阻止反射攻击
     */
    private static boolean flag = true;

    private LazySingleton() {
        if (flag) {
            flag = false;
        }
        if (lazySingleton != null) {
            throw new RuntimeException("单例构造器禁止反射调用");
        }
    }

    /**
     * 这里需要注意，synchronized修饰静态方法相当于锁的是这个类的class文件，
     * 如果修饰的不是静态方法，相当于锁的是堆内存中生成的对象；
     * 这里由于添加了synchronized关键字，解决了线程安全问题，但是这个关键字性能开销大，需要进行优化！
     *
     * @return
     */
    public synchronized static LazySingleton getInstance() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class objectClass = LazySingleton.class;
        Constructor c = objectClass.getDeclaredConstructor();
        c.setAccessible(true);

        LazySingleton o1 = LazySingleton.getInstance();

        Field flag = o1.getClass().getDeclaredField("flag");
        flag.setAccessible(true);
        flag.set(o1, true);


        LazySingleton o2 = (LazySingleton) c.newInstance();

        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o1 == o2);
    }

}
